<?php
{
    /**
     * SQL语句执行功能
     * */
    class SqlHelper
    {


        /* mysql连接信息 */
        private $hostname = null;
        // 端口
        private $port = null;
        // 用户名
        private $username = null;
        // 密码
        private $userpwd = null;
        // 数据库名称
        private $dbName = null;
        // PDO对象stmt
        private $PDO = null;
        // 数据库连接对象
        private $conn = null;


        // 构造函数
        function __construct()
        {
            $configs = $GLOBALS["configs"]["db"];
            $this -> hostname = $configs['HostName'];
            $this -> port = $configs['Port'];
            $this -> username = $configs['UserName'];
            $this -> userpwd = $configs['UserPassword'];
            $this -> dbName = $configs['DatabaseName'];
        }

        /**
         * ************************************* 普通 开始 *******************************
         */

        #region 打开链接
        /**
         * 打开连接
         */
        public function Open()
        {
            try
            {
                $this->conn = mysqli_init();
                $this -> conn -> options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, true); // 解决int和float和double类型变string的问题，但是无法解决decimal问题
                $this -> conn->real_connect($this -> hostname, $this -> username, $this -> userpwd, $this -> dbName, $this -> port);
                $this -> conn -> query('set names utf8');
            }
            catch (Exception $ex)
            {
                echo "连接失败：" . $this -> conn -> connect_error;
                exit;
            }
        }
        #endregion

        #region 关闭连接
        /**
         * 关闭连接
         */
        public function Close()
        {
            if ($this -> conn != null)
            {
                $this -> conn -> close();
            }
        }
        #endregion

        #region 执行SELECT语句,返回结果集
        /**
         * 执行SELECT语句,返回结果集
         * @param $sql string 执行的SQL语句
         * @return array 结果集
         * @throws Exception 执行失败异常
         */
        public function getAll($sql)
        {
            $this -> Open();
            $result = $this -> conn -> query($sql);
            if ($result === false)
            {
                // 执行失败
                $error = $this -> conn -> error;
                $this -> Dispose($result);
                $this -> Close();
                throw new Exception('[SQL语句：' . $sql . '执行失败]' . $error, 0);
            }
            else
            {
                // 执行成功
                $resArr = array();
                while ($row = $result -> fetch_assoc())
                {
                    $resArr[] = $row;
                }
                $this -> Dispose($result);
                $this -> Close();
                return $resArr;
            }
        }
        #endregion

        #region 执行SELECT语句,返回首行首列
        /**
         * 执行SELECT语句,返回首行首列
         * @param $sql string 执行的SQL语句
         * @return object 结果
         * @throws Exception 失败异常
         */
        public function getOne($sql)
        {
            $this -> Open();
            $result = $this -> conn -> query($sql);
            if ($result === false)
            {
                // 执行失败
                $error = $this -> conn -> error;
                $this -> Close();
                throw new Exception('[SQL语句：' . $sql . '执行失败]' . $error, 0);
            }
            else
            {
                $row = $result -> fetch_row();
                $this -> Dispose($result);
                $this -> Close();

                // 判断是否有结果集
                if ($row == null)
                {
                    return null;
                }
                return $row[0];
            }
        }
        #endregion

        #region 执行INSERT,UPDATE,DELETE语句
        /**
         * 执行INSERT,UPDATE,DELETE语句
         * @param $sql
         * @return mixed
         * @throws Exception
         */
        public function Query($sql)
        {
            $this -> Open();
            $result = $this -> conn -> query($sql);

            if ($result === false)
            { // 执行失败
                // 提取错误信息
                $error = $this -> conn -> error;
                $this -> Close();
                throw new Exception('[SQL语句：' . $sql . '执行失败]' . $error, 0);
            }
            else
            {   // 执行成功
                $ret = $this -> conn -> affected_rows; // 返回受影响行
                $this -> Close();
                return $ret;
            }
        }
        #endregion

        #region 执行INSERT返回自增列
        /**
         * 执行INSERT返回自增列
         * @param $sql
         * @return mixed
         * @throws Exception
         */
        public function QueryInserID($sql)
        {
            $this -> Open();
            $result = $this -> conn -> query($sql);

            if ($result === false)
            {   // 执行失败
                $error = $this -> conn -> error; // 提取错误信息
                $this -> Close();
                throw new Exception('[SQL语句：' . $sql . '执行失败]' . $error, 0);
            }
            else
            {   // 执行成功
                $ret = $this -> conn -> insert_id; // 返回自增编号
                $this -> Close();
                return $ret;
            }
        }
        #endregion

        #region 释放结果集
        /**
         * 释放结果集
         * @param object $result 参数
         */
        public function Dispose($result)
        {
            if ($result !== false)
            {
                $result -> free();
            }
        }
        #endregion

        /**
         * ************************************* 普通 结束 *******************************
         */

        /**
         * ************************************* PDO 开始 *******************************
         */

        #region PDO打开链接
        /**
         * PDO打开链接
         */
        public function PDOOpen()
        {
            $dsn = "mysql:dbname=" . $this -> dbName . ";host=" . $this -> hostname . ";port=" . $this -> port;
            try
            {
                $this -> conn = new PDO($dsn, $this -> username, $this -> userpwd);
            }
            catch (PDOException $e)
            {
                die('<br />不能连接到数据库:<br/>' . $e);
            }
        }
        #endregion

        #region PDO关闭链接
        /**
         * PDO关闭链接
         */
        public function PDOClose()
        {
            $this -> PDO -> closeCursor();
        }
        #endregion

        // PDO生成预编译
        public function PDOPrepare($sql)
        {
            $this -> PDOOpen();
            $this -> PDO = $this -> conn -> prepare($sql);
        }

        // PDO绑定预编译参数
        public function PDOBindParameter($paramStrng, $paramValue)
        {
            $this -> PDO -> bindValue($paramStrng, $paramValue);
        }

        // PDO执行INSERT,DELETE,UPDASTE查询,返回影响行
        public function PDOQuery()
        {
            // 获取查询结果集
            $result = $this -> PDO -> execute();

            // 判断执行是否成功
            if ($result === false)
            { // 执行失败
                // 执行失败
                $error = $this -> PDO -> errorInfo(); // 获取错误信息息
                $this -> PDOClose(); // 关闭PDO
                throw new Exception($error[0] . "|" . $error[1] . "|" . $error[2], 0); // 拼接错误信息
            }
            else
            { // 执行成
                // 记录受影响的行
                $retValue = $this -> PDO -> rowCount();
                $this -> PDOClose(); // 关闭
                return $retValue; // 返回影响行
            }
        }

        // PDO执行SELECT查询,返回结果集
        public function PDOGetAll()
        {
            $result = $this -> PDO -> execute();
            if ($result === false)
            {
                // 执行失败
                $error = $this -> PDO -> errorInfo(); // 获取错误信息
                $this -> PDOClose(); // 关闭PDO
                throw new Exception($error[0] . "|" . $error[1] . "|" . $error[2], 0); // 拼接错误信息
            }
            else
            {
                $arr = array();
                while ($row = $this -> PDO -> fetch(PDO::FETCH_ASSOC))
                {
                    $arr[] = $row;
                }
                $this -> PDOClose();
                return $arr;
            }
        }

        // PDO执行SELECT查询，返回首行首列
        public function PDOGetOne()
        {
            $result = $this -> PDO -> execute();
            if ($result === false)
            {
                // 执行失败
                $error = $this -> PDO -> errorInfo(); // 获取错误信息
                $this -> PDOClose(); // 关闭PDO
                throw new Exception($error[0] . "|" . $error[1] . "|" . $error[2], 0); // 拼接错误信息
            }
            else
            {
                $row = $this -> PDO -> fetch(PDO::FETCH_COLUMN);
                $this -> PDOClose();
                if ($row === false)
                {
                    return null;
                }
                return $row;
            }
        }

        // PDO执行INSERT,返回自增ID
        public function PODQueryInserid()
        {
            $result = $this -> PDO -> execute();
            if ($result === false)
            { // 执行失败
                // 提取错误信息
                $error = $this -> PDO -> errorInfo(); // 获取错误信息
                $this -> PDOClose(); // 关闭PDO
                throw new Exception($error[0] . "|" . $error[1] . "|" . $error[2], 0); // 拼接错误信息
            }
            else
            {
                // 记录自增编号
                $retValue = $this -> conn -> lastInsertId();
                $this -> PDOClose();
                return $retValue;
            }
        }

        /**
         * ************************************* PDO 结束 *******************************
         */

        /**
         * ************************************* Transaction 开始 *******************************
         */
        // 开启事务
        public function BeginTrans()
        {
            $this -> ExecuteNonQuery("BEGIN");
        }

        // 提交事务
        public function CommitTrans()
        {
            $this -> ExecuteNonQuery("COMMIT");
        }

        // 回滚
        public function RollbackTrans()
        {
            $this -> ExecuteNonQuery("ROLLBACK");
        }

        /**
         * ************************************* Transaction 结束 *******************************
         */
    }
}
?>